﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Collections.Generic;

namespace Xceed.Silverlight.ListBox
{
  public class HierarchicalGroupValueControl : ItemsControl
  {
    #region Constructor
    public HierarchicalGroupValueControl()
    {
      // Style is never overridden, no need to set DefaultStyleKey
      this.SeparatorVisibility = Visibility.Visible;
    }
    #endregion

    #region ItemContainerStyle Property

    public static readonly DependencyProperty ItemContainerStyleProperty = DependencyProperty.Register(
      "ItemContainerStyle",
      typeof( Style ),
      typeof( HierarchicalGroupValueControl ),
      new PropertyMetadata( ( Style )null ) );

    public Style ItemContainerStyle
    {
      get
      {
        return ( Style )this.GetValue( HierarchicalGroupValueControl.ItemContainerStyleProperty );
      }
      set
      {
        this.SetValue( HierarchicalGroupValueControl.ItemContainerStyleProperty, value );
      }
    }

    #endregion

    #region GroupValueDataTemplates Property

    public static readonly DependencyProperty GroupValueDataTemplatesProperty = DependencyProperty.Register(
      "GroupValueDataTemplates",
      typeof( List<GroupValueDataTemplate> ),
      typeof( HierarchicalGroupValueControl ),
      new PropertyMetadata( ( List<GroupValueDataTemplate> )null ) );

    public List<GroupValueDataTemplate> GroupValueDataTemplates
    {
      get
      {
        return ( List<GroupValueDataTemplate> )this.GetValue( HierarchicalGroupValueControl.GroupValueDataTemplatesProperty );
      }
      set
      {
        this.SetValue( HierarchicalGroupValueControl.GroupValueDataTemplatesProperty, value );
      }
    }

    #endregion

    #region ParentHierarchicalGroupValueControl Attached Property

    public static readonly DependencyProperty ParentHierarchicalGroupValueControlProperty = DependencyProperty.RegisterAttached(
      "ParentHierarchicalGroupValueControl",
      typeof( HierarchicalGroupValueControl ),
      typeof( HierarchicalGroupValueControl ),
      new PropertyMetadata( ( HierarchicalGroupValueControl )null ) );

    public static HierarchicalGroupValueControl GetParentHierarchicalGroupValueControl( DependencyObject obj )
    {
      return ( HierarchicalGroupValueControl )obj.GetValue( HierarchicalGroupValueControl.ParentHierarchicalGroupValueControlProperty );
    }

    public static void SetParentHierarchicalGroupValueControl( DependencyObject obj, HierarchicalGroupValueControl value )
    {
      obj.SetValue( HierarchicalGroupValueControl.ParentHierarchicalGroupValueControlProperty, value );
    }

    #endregion


    #region SeparatorVisibility Property
    public Visibility SeparatorVisibility
    {
      get;
      set;
    }
    #endregion

    #region Protected Methods
    protected override DependencyObject GetContainerForItemOverride()
    {
      return new HierarchicalGroupValueItem();
    }

    protected override void PrepareContainerForItemOverride( DependencyObject element, object item )
    {
      base.PrepareContainerForItemOverride( element, item );
      HierarchicalGroupValueItem container = element as HierarchicalGroupValueItem;
      FieldNameValuePair fieldNameValuePair = item as FieldNameValuePair;

      if( container == null )
        throw new ListBoxInternalException( "container isn't a HierarchicalGroupValueItem." );

      if( fieldNameValuePair == null )
        throw new ListBoxInternalException( "item isn't a FieldNameValuePair" );

      DataTemplate contentTemplate = null;

      // Get the content template associated to the object we want to display.
      if( this.GroupValueDataTemplates != null )
      {
        // Look for a DataTemplate for the field name
        contentTemplate = m_dataTemplateSelector.Select( fieldNameValuePair.FieldName, this.GroupValueDataTemplates );

        if( contentTemplate == null )
          contentTemplate = this.ItemTemplate;

        if( contentTemplate != null )
        {
          container.ContentTemplate = contentTemplate;
        }
        else
        {
          container.ClearValue( HierarchicalGroupValueItem.ContentTemplateProperty );
        }
      }

      // Sets the container style if a style has been specified
      // on the group configuration.
      if( this.ItemContainerStyle != null )
      {
        container.Style = this.ItemContainerStyle;
      }
      else
      {
        container.ClearValue( HierarchicalGroupValueItem.StyleProperty );
      }

      // The data context of the container is the GroupValue. We don't want
      // the pair (groupValue / fieldName) to be the DataContext. This pair
      // is only used to get the Content template with the selector.
      container.DataContext = fieldNameValuePair.Value;

      // Setting IsRoot and IsLeaf property on the container
      container.IsRoot = fieldNameValuePair.IsRoot;
      container.IsLeaf = fieldNameValuePair.IsLeaf;

      HierarchicalGroupValueControl.SetParentHierarchicalGroupValueControl( container, this );

    }

    protected override void ClearContainerForItemOverride( DependencyObject element, object item )
    {
      base.ClearContainerForItemOverride( element, item );

      HierarchicalGroupValueItem container = element as HierarchicalGroupValueItem;

      if( container != null )
      {
        container.ClearValue( HierarchicalGroupValueControl.ParentHierarchicalGroupValueControlProperty );
      }
    }

    #endregion

    #region Private Members

    HierarchicalContentTemplateSelector m_dataTemplateSelector = new HierarchicalContentTemplateSelector();

    #endregion

    #region Nested Classes

    private class HierarchicalContentTemplateSelector
    {
      #region Constructor
      internal HierarchicalContentTemplateSelector()
      {

      }
      #endregion

      internal DataTemplate Select( string fieldName, List<GroupValueDataTemplate> groupValueDataTemplates )
      {
        // Look for the field name across the group value DataTemplate
        foreach( GroupValueDataTemplate groupValueDataTemplate in groupValueDataTemplates )
        {
          if( groupValueDataTemplate.FieldNames.Contains( fieldName ) )
            return groupValueDataTemplate.Template;
        }

        return null;

      }

    }


    #endregion

  }
}
